import { Inject } from '@midwayjs/core';
import { JwtService } from '@midwayjs/jwt';
import { Middleware, IMiddleware } from '@midwayjs/core';
import { NextFunction, Context } from '@midwayjs/koa';

// 白名单，不需要token校验的jwt路由
// 配置不需要token
const whiteList = [
  '/',
  '/captchaImage',
  '/login',
  '/logout',
  '/public',
  '/jx3/model/list',
  '/methods/upload',
];

const wxApi = [
  '/system/user/wxLogin',
  '/system/user/userInfo',
  '/jx3/wages/getWagesDetail',
];

whiteList.push(...wxApi);

@Middleware()
export class JwtMiddleware implements IMiddleware<Context, NextFunction> {
  @Inject()
  jwtService: JwtService;

  resolve() {
    return async (ctx: Context, next: NextFunction) => {
      // 获取路由地址
      const originUrl = ctx.request.url;
      const routerUrl = originUrl.split('?')[0];

      // 如果当前地址不在白名单里，校验token，否则直接放行
      if (!whiteList.includes(routerUrl)) {
        const header = ctx.request.header;
        // 此处取token值，需要和前端约定好格式
        const token = header.authorization
          ? header.authorization.substring(7)
          : null;
        // 服务端token校验是否过期
        if (!ctx.cookies.get('token')) {
          console.log('服务端token校验失败');
          ctx.throw(401, 'token已失效，请重新登录');
        }
        // 客户端校验token是否有效
        if (token) {
          try {
            const decoded: any = await this.jwtService.verify(token, {
              complete: true,
            });
            if (decoded.payload.iat > decoded.payload.exp) {
              ctx.throw(401, 'token已失效，请重新登录');
            } else {
              await next();
            }
          } catch (e) {
            // todo:待优化，code不生效，返回500
            console.log('jwt.middleware捕捉错误', e);
            ctx.throw(e.code, e);
          }
        } else {
          ctx.throw('token值不能为空');
        }
      } else {
        await next();
      }
    };
  }

  static getName(): string {
    return 'jwt';
  }
}
